<?php

namespace pmvc\ioc\xml;

use pmvc\ioc\PropertyDescriptor;
use pmvc\ioc\ObjectDescriptor;
use pmvc\util\FileUtil;
use pmvc\util\XMLUtil;

use DOMElement;

/**
 * An extension for using properties from
 * a {@link Properties} object\file in the
 * xml context
 *
 */
class PropertiesExtension
	implements Extension {

	/**
	 * {@inheritDoc}
	 */
	public function process(DOMElement $element, ParseContext $pc) {

		// get some values
		$addEnvironmentVariables		= XMLUtil::getAttributeValue($element, "add-env-vars",		"false");
		$environmentVariablesOverride	= XMLUtil::getAttributeValue($element, "env-vars-override",	"false");

		// build file list
		$requiredFiles = Array();
		$optionalFiles = Array();
		
		// create file descriptor from attributes
		$fileAttr = XMLUtil::getAttributeValue($element, 'file');
		if (isset($fileAttr)) {
			$file = FileUtil::getRelativePath($fileAttr, $pc->getXmlFile());
			if (!$file) { $file = $fileAttr; }
			$propDesc = new PropertyDescriptor(NULL, $file, PropertyDescriptor::TYPE_STRING);
			if (XMLUtil::getAttributeValue($element, 'optional', 'false') != 'true') {
				$requiredFiles[] = $propDesc;
			} else {
				$optionalFiles[] = $propDesc;
			}

		// create file descriptors from file sub-elements
		} else {
			foreach ($pc->getXPath()->query('file', $element) as $fileEl) {
				$file = FileUtil::getRelativePath($fileEl->textContent, $pc->getXmlFile());
				if (!$file) { $file = $fileEl->textContent; }
				$propDesc = new PropertyDescriptor(NULL, $file, PropertyDescriptor::TYPE_STRING);
				if (strtolower(XMLUtil::getAttributeValue($fileEl, 'optional', 'false')) != 'true') {
					$requiredFiles[] = $propDesc;
				} else {
					$optionalFiles[] = $propDesc;
				}
			}
		}

		// error if there aren't any files to import
		if (empty($requiredFiles) && empty($optionalFiles)) {
			throw new Exception("No files specified for properties");
		}
		
		// create ObjectDescriptor for PropertiesFactory
		$propertiesId = XMLUtil::getAttributeValue($element, 'id');
		if (!isset($propertiesId)) {
			$propertiesId = uniqid('', TRUE) . '#Properties';
		}

		// get the factory
		$objectFactory = $pc->getObjectFactory();

		// create descriptor for Properties object
		$propertiesDesc = new ObjectDescriptor(
			$propertiesId, "pmvc\Properties", $propertiesId, Array(
				new PropertyDescriptor("addEnvironmentVariables", 		$addEnvironmentVariables=="true", 		PropertyDescriptor::TYPE_BOOLEAN),
				new PropertyDescriptor("environmentVariablesOverride", 	$environmentVariablesOverride=="true", 	PropertyDescriptor::TYPE_BOOLEAN),
				new PropertyDescriptor("requiredPropertyFiles", 		$requiredFiles, 						PropertyDescriptor::TYPE_ARRAY),
				new PropertyDescriptor("optionalPropertyFiles", 		$optionalFiles, 						PropertyDescriptor::TYPE_ARRAY)
			),
			Array(), TRUE, FALSE, NULL, FALSE, NULL, NULL, "pmvc\ioc\PropertiesFactory");
		$objectFactory->addObjectDescriptor($propertiesDesc);
		
		// create post processor
		$id = uniqid('', TRUE)."#PropertiesDescriptorPostProcessor";
		$desc = new ObjectDescriptor(
			$id, "pmvc\ioc\PropertiesDescriptorPostProcessor", $id, Array(
				new PropertyDescriptor("properties", $propertiesId, PropertyDescriptor::TYPE_REF)
			));
		$objectFactory->addObjectDescriptor($desc);

	}
}